import json
import random
import time
import urllib.parse

import requests
from redis import ConnectionPool, StrictRedis

from config.secure import REDIS_URL


class RedisClient(object):

    def __init__(self, db):
        self.db = db
        self.pool = ConnectionPool(**{
            'host': REDIS_URL,
            'port': 6379,
            'db': self.db,
            'password': 950218
        })
        self.client = StrictRedis(connection_pool=self.pool)

    def reConnect(self):
        try:
            self.client.ping()
        except:
            self.client = StrictRedis(connection_pool=self.pool)

    def GetTask(self):
        taskId = self.client.rpop('local_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    # def GetTestTask(self):
    #     taskId = self.client.rpop('test_local_task')
    #     if taskId:
    #         return str(taskId, encoding='utf-8')
    #     else:
    #         return None

    def GetWriterTask(self):
        taskId = self.client.rpop('writer_local_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetPreLocalTask(self):
        taskId = self.client.rpop('pre_local_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetBatchLocalTask(self):
        taskId = self.client.rpop('batch_local_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetPolymerizationTask(self):
        taskId = self.client.rpop('polymerization_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetLastTask(self):
        taskId = self.client.rpop('last_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetPersonalCheckTask(self):
        taskId = self.client.rpop('personal_check_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetPreInternetTask(self):
        taskId = self.client.rpop('pre_internet_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetWriterPreInternetTask(self):
        taskId = self.client.rpop('writer_pre_internet_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetInternetTask(self):
        taskId = self.client.rpop('internet_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetWriterInternetTask(self):
        taskId = self.client.rpop('writer_internet_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetBatchInternetTask(self):
        taskId = self.client.rpop('batch_internet_task')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def RecoverKeyWords(self, order_number, keywords):
        self.client.lpush(f'keywords_internet_{order_number}', keywords)

    def CheckTaskStatus(self, task):
        taskId = self.client.hget('tasks_status', task)
        if taskId:
            return int(taskId)
        else:
            return None

    def UpdateTaskStatus(self, task, status):
        self.client.hset('tasks_status', task, status)

    def DeleteTaskStatus(self, task):
        self.client.hdel('tasks_status', task)

    def GetInternetTaskKeyWords(self, order_number):
        taskId = self.client.lpop(f'keywords_internet_{order_number}')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def GetWirterLocalTaskKeyWords(self, order_number):
        taskId = self.client.lpop(f'writer_keywords_local_{order_number}')
        if taskId:
            return str(taskId, encoding='utf-8')
        else:
            return None

    def set_cookies(self, ip, cookies):
        self.reConnect()
        self.client.hset(ip, 'baidu_cookie_dict', cookies)

    def get_cookies(self, ip):
        self.reConnect()
        return str(self.client.hget(ip, 'baidu_cookie_dict'), encoding='utf-8')

    def get_baiducookies(self, ip):
        self.reConnect()
        return str(self.client.hget(ip, 'baidu_cookies_string'), encoding='utf-8').encode('utf-8').decode('latin-1')

    def set_referer(self, ip, url):
        self.reConnect()
        self.client.set('referer', url)

    def get_referer(self, ip):
        self.reConnect()
        return str(self.client.hget(ip, 'referer'), encoding='utf-8')

    def push_suggest_sentence(self, data):
        self.reConnect()
        self.client.rpush('suggest', data)

    def push_polymerize(self, order_number, data):
        self.reConnect()
        number = order_number.replace('last_', '').replace('polymerize_', '')
        if self.client.exists(f'hset_{number}'):
            if not self.client.sismember(f'hset_{number}', data):
                self.client.sadd(f'hset_{number}', data)
                self.client.rpush(order_number, data)
        else:
            self.client.sadd(f'hset_{number}', data)
            self.client.rpush(order_number, data)

    def push_no_last_polymerize(self, order_number, data):
        self.reConnect()
        self.client.rpush(order_number, data)

    def clear_url_param(self, ip):
        self.reConnect()
        res = self.client.hgetall(ip)
        for key in res.keys():
            if key not in [b'baidu_cookies_string', b'referer', b'baidu_cookie_dict']:
                self.client.hdel(ip, key)

    def set_url_param(self, ip, name, value):
        self.reConnect()
        self.client.hset(ip, name, value)

    def get_url_param(self, ip):
        self.reConnect()
        res = self.client.hgetall(ip)
        return_dict = {}
        for key in res.keys():
            if key not in [b'baidu_cookies_string', b'referer', b'baidu_cookie_dict']:
                field = str(key, encoding='utf-8')
                value = urllib.parse.quote(str(res[key], encoding='utf-8'))
                value = value.replace(' ', '%20')
                value = value.replace('/', '%2F')
                value = value.replace('?', '%3F')
                value = value.replace('#', '%23')
                value = value.replace('&', '%26')
                value = value.replace('=', '%3D')
                if value != '':
                    return_dict[field] = value
        return return_dict

    def get_suggest_sentence(self):
        self.reConnect()
        sentence = self.client.lpop('suggest')
        if sentence:
            return str(sentence, encoding='utf-8')
        else:
            return None

    def copy_params(self, target):
        self.reConnect()
        params = self.client.hgetall('111.173.119.77')
        for item in params.keys():
            self.client.hset(target, item, params[item])

    def check_task_status(self):
        self.reConnect()
        tasks = self.client.hgetall('tasks_status')
        if tasks:
            for item in tasks.keys():
                now = int(time.time())
                task = int(str(item, encoding='utf-8'))
                status = self.client.hget('tasks_status', item)
                if status == b'0' and now - task > 60 * 15:
                    print(now - task)
                    self.client.lpush('local_task', task)
                    self.client.lpush('pre_internet_task', task)

    def push_selenium(self, ip, url):
        self.reConnect()
        self.client.rpush('selenium', f'{ip}####{url}')

    def IncrTaskCount(self):
        self.reConnect()
        current = int(self.client.get('task_count'))
        self.client.set('task_count', current + 1)

    def DecTaskCount(self):
        self.reConnect()
        current = int(self.client.get('task_count'))
        self.client.set('task_count', current - 1)

    def timestr2int(self, timestr):
        return time.mktime(time.strptime(timestr, '%Y-%m-%d %H:%M:%S'))

    def setADSL(self, data):
        self.reConnect()
        self.client.hset('adsl', str(data['expire']), f'{data["ip"]}:{data["port"]}')

    def randoms(self):
        strings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
        random_str = ''.join(random.sample(strings, 3))
        return random_str

    def getADSL(self):
        self.reConnect()
        key = 'adsl'
        try:
            keys = self.client.hkeys(key)
            if keys is None:
                return None
            else:
                selectkey = random.choice(keys)
                ip = self.client.hget(key, selectkey)
                return str(ip.decode())
        except:
            return None

    def init_adsl(self, count):
        for i in range(count):
            res = requests.get(
                'http://api.tianqiip.com/getip?secret=qhzhvo0w&num=1&type=json&port=2&ts=1&sign=80a0d978f384add279308174f0c78058')
            if res.status_code == 200:
                print(json.loads(res.content))
                data = json.loads(res.content)
                for item in data['data']:
                    data = {
                        'ip': item['ip'],
                        'port': item['port'],
                        'expire': str(int(self.timestr2int(item['expire']))) + '-' + self.randoms()
                    }
                    self.setADSL(data)
            else:
                print(res.text)


def copy(ip, to_ip):
    target_r = RedisClient(1)
    from_r = RedisClient(0)
    params = from_r.client.hgetall(ip)
    res = target_r.client.hgetall(to_ip)
    for key in res.keys():
        target_r.client.hdel(to_ip, key)
    for item in params.keys():
        target_r.client.hset(to_ip, item, params[item])


if __name__ == '__main__':
    copy('111.173.119.77', '111.173.89.244')

    # r.check_task_status()
